package com.hky.algorithm.mahjongGame;

import com.hky.algorithm.realize.Player;
import com.hky.algorithm.realize.Type;

import java.util.*;

/**
 * 对局中的数据
 */
public class GameData {
    // 所有类型
    public Type[] types = new Type[]{Type.TONG, Type.TIAO, Type.WAN};

    // 剩余还没有摸得牌
    public List<Card> leftCards = new ArrayList<>(108);

    // 玩家
    public List<GamePlayer> players = new ArrayList<>(4);

    /**
     * 洗牌
     */
    private void initLeftCards() {
        leftCards.clear();

        // 初始化牌
        for (Type type : types) {
            for (int i = 1; i <= 9; i++) {
                for (int j = 0; j < 4; j++) leftCards.add(new Card(i, type));
            }
        }

        // 洗牌
        Collections.shuffle(leftCards);
    }

    /**
     * 每个用户发13张牌，第一个用户默认是庄家，发14张牌
     */
    private void initPlayers() {
        // 清理、初始化玩家危险牌数据
        for (GamePlayer player : players) {
            player.clearGamePlayer();
            player.initGamePlayer(this);
        }

        // 发牌
        for (GamePlayer player : players) {
            for (int j = 0; j < 13; j++) {
                Card card = getCard();
                player.fetchCard(card);
            }
        }
    }

    /**
     * 初始化对局数据，一般在添加完用户后调用
     */
    public void initGameData() {
        initLeftCards();
        initPlayers();
    }

    /**
     * 摸一张牌，如果没有牌就返回空
     *
     * @return 一张牌
     */
    private Card getCard() {
        return leftCards.size() > 0 ? leftCards.remove(leftCards.size() - 1) : null;
    }

    /**
     * 添加玩家
     *
     * @param player 玩家
     */
    public void addPlayer(GamePlayer player) {
        players.add(player);
        player.addSelfToSelfGame();
    }

    /**
     * 给玩家发一张牌=玩家摸一张牌
     *
     * @param player 玩家
     * @return true 还有牌，flase 没有牌对局结束
     */
    public Card distributeCard(GamePlayer player) {
        Card card = getCard();
        if(card == null) return card;

        player.fetchCard(card);

        return card;
    }

    public static void main(String[] args) {
//        GameData gameData = new GameData();
//        gameData.players.add(new GamePlayer("0", "小强"));
//        gameData.players.add(new GamePlayer("1", "张三"));
//
//        gameData.initGameData();
//
//        GamePlayer xq = gameData.players.get(0);
//        GamePlayer zs = gameData.players.get(1);
//
//        int[][] xqarr = new int[3][10], zsarr = new int[3][10];
//        for (Card card : gameData.leftCards) {
//            xqarr[card.type.ordinal()][card.num]++;
//            zsarr[card.type.ordinal()][card.num]++;
//        }
//
//        for (Map.Entry<Card, Integer> entry : zs.cardMap.entrySet()) {
//            Card card = entry.getKey();
//            xqarr[card.type.ordinal()][card.num] += entry.getValue();
//        }
//
//        for (Map.Entry<Card, Integer> entry : xq.cardMap.entrySet()) {
//            Card card = entry.getKey();
//            zsarr[card.type.ordinal()][card.num] += entry.getValue();
//        }
//
//        System.out.println(xq.name + " :: " + xq.cardMap);
//        System.out.println(xq.name + " :: " + Arrays.toString(xq.game.terms[0].cards) + Arrays.toString(xq.game.terms[1].cards) + Arrays.toString(xq.game.terms[2].cards));
//        System.out.println(xq.name + " :: " + Arrays.toString(xqarr[0]) + Arrays.toString(xqarr[1]) + Arrays.toString(xqarr[2]));
//
//        System.out.println(zs.name + " :: " + zs.cardMap);
//        System.out.println(zs.name + " :: " + Arrays.toString(zs.game.terms[0].cards) + Arrays.toString(zs.game.terms[1].cards) + Arrays.toString(zs.game.terms[2].cards));
//        System.out.println(zs.name + " :: " + Arrays.toString(zsarr[0]) + Arrays.toString(zsarr[1]) + Arrays.toString(zsarr[2]));
    }

    /**
     * 获取一个玩家
     *
     * @param sessionId 玩家客户端id
     * @return 玩家
     */
    public GamePlayer getPlayerBySessionId(String sessionId) {
        for (GamePlayer player : players) {
            if(sessionId.equals(player.sessionId)) return player;
        }
        return null;
    }

    /**
     * 对手出了一张牌
     * @param player 对手
     * @param card 牌
     * @param num 数量
     */
    public void outCardRival(GamePlayer player, Card card, int num) {
        for (GamePlayer gamePlayer : players) {
            if (gamePlayer.equals(player)) continue;
            gamePlayer.game.subCardToTerm(card, num);
        }
    }

    /**
     * 定缺
     * 1 自己定缺
     * 2 更新其他对手中的game lack数据
     *
     * @param player 定缺的玩家
     * @param type 定缺的牌
     */
    public void defineLack(GamePlayer player, Type type) {
        player.defineLack(type);
    }

    /**
     * 自己要碰或者杠
     */
    public void pengOrGang(GamePlayer player, GangItem gangItem) {
        player.selfGangOrPeng(gangItem);
        // 更新别人的手牌数据
        for (GamePlayer gamePlayer : players) {
            if (gamePlayer.equals(player)) continue;
            gamePlayer.rivalGangOrPeng(gangItem);
        }
    }
}